package com.scientific.research.gobang.service.match.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scientific.research.gobang.mapper.SystemMapper;
import com.scientific.research.gobang.pojo.SystemMessage;
import com.scientific.research.gobang.service.CodeAndCodeService;
import com.scientific.research.gobang.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service("codeAndCodeServiceImpl")
public class CodeAndCodeServiceImpl implements CodeAndCodeService {

    @Autowired
    public RunCodeServiceImpl userOne;
    @Autowired
    public RunCodeServiceImpl userTwo;
    @Autowired
    public SystemMapper systemMapper;

    private String runTime;//记录用户运行代码时的时间

    //执行一次双方的代码对弈，包括用户1黑vs用户2白、用户1白vs用户2黑
    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    @Override
    public Map CodeAndCodeOnce(String OneName, String OneLanguage, String userOneCode, String TwoName, String TwoLanguage, String userTwoCode) {
        //代码执行过程中的错误信息
        Map<String, String> finalResult = new HashMap<>();
        String errorMessage = "";

        //初始化用户1和用户2
        userOne.thisInit(OneName, OneLanguage);
        userTwo.thisInit(TwoName, TwoLanguage);

        //拼接用户的代码并存储至相应目录
        String userOneMainCode = "", userTwoMainCode = "";
        String userOneFileName = "", userTwoFileName = "";
        int userOneTag = 0, userTwoTag = 0;
        if ("java".equals(OneLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeJava");
            userOneMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userOneTag = userOneMainCode.indexOf("public class java") + 18;
            userOneFileName = "java.java";
        } else if ("python".equals(OneLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodePython");
            userOneMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userOneTag = 3;//待测量
            userOneFileName = "python.py";
        } else if ("c++".equals(OneLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeC++");
            userOneMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userOneTag = userOneMainCode.indexOf("int** map = new int*[15];") + 26;
            userOneFileName = "c++.cpp";
        } else if ("c".equals(OneLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeC");
            userOneMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userOneTag = 3;//待定
            userOneFileName = "c.c";
        }

        if ("java".equals(TwoLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeJava");
            userTwoMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userTwoTag = userTwoMainCode.indexOf("public class java") + 18;
            userTwoFileName = "java.java";
        } else if ("python".equals(TwoLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodePython");
            userTwoMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userTwoTag = 3;//待测量
            userTwoFileName = "python.py";
        } else if ("c++".equals(TwoLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeC++");
            userTwoMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userTwoTag = userTwoMainCode.indexOf("int** map = new int*[15];") + 26;
            userTwoFileName = "c++.cpp";
        } else if ("c".equals(TwoLanguage)) {
            QueryWrapper<SystemMessage> wrapper = new QueryWrapper<>();
            wrapper.eq("key_message", "mainCodeC");
            userTwoMainCode = systemMapper.selectOne(wrapper).getValueMessage();
            userTwoTag = 3;//待定
            userTwoFileName = "c.c";
        }
        String between = userOneMainCode.substring(0, userOneTag);
        userOneCode = between + "\n" + userOneCode + "\n" + userOneMainCode.substring(userOneTag);
        between = userTwoMainCode.substring(0, userTwoTag);
        userTwoCode = between + "\n" + userTwoCode + "\n" + userTwoMainCode.substring(userTwoTag);
        between = userOne.appendPath(RunCodeServiceImpl.basePath, OneName.replace(".", "-"));
        between = userOne.appendPath(between, userOneFileName);
        FileUtils.writer(between, userOneCode, false);
        between = userOne.appendPath(RunCodeServiceImpl.basePath, TwoName.replace(".", "-"));
        between = userOne.appendPath(between, userTwoFileName);
        FileUtils.writer(between, userTwoCode, false);
        ;

        //编译双方玩家的代码
        String runResult = "";
        int winnerJurgeOne = 0, winnerJurgeTwo = 0;
        String userOneResult = userOne.setAndCompile(OneName, OneLanguage);
        if (userOneResult.length() != 0) {
            runResult = "编译错误1" + "$" + userOneResult + "$";
            winnerJurgeTwo = 1;
            errorMessage = "notNull";
        }
        String userTwoResult = userTwo.setAndCompile(TwoName, TwoLanguage);
        if (userTwoResult.length() != 0) {
            runResult = "编译错误2" + "$" + userTwoResult + "$";
            winnerJurgeOne = 1;
            errorMessage = "notNull";
        }
        if ("".equals(errorMessage)) {
            String result;
            String process = userOne.appendPath(RunCodeServiceImpl.basePath, userOne.getUserName());
            process = userOne.appendPath(process, "input.txt");
            result = BlackFirstRun(0);
            process = FileUtils.read(process);
            if ("".equals(result)) {
                runResult += "winner:none$" + process + "$" + runTime + "$";
            } else if ("no".equals(result)) {
                runResult += "winner:2$" + process + "$" + runTime + "$";
                winnerJurgeTwo = 1;
            } else if ("yes".equals(result)) {
                runResult += "winner:1$" + process + "$" + runTime + "$";
                winnerJurgeOne = 1;
            } else {
                if (result.substring(0, result.indexOf("#")).equals(OneName)) {
                    runResult += "运行错误1$" + result.substring(result.indexOf("#") + 1) + "$";
                    winnerJurgeTwo = 1;
                } else {
                    runResult += "运行错误2$" + result.substring(result.indexOf("#") + 1) + "$";
                    winnerJurgeOne = 1;
                }
            }

            String path = userOne.appendPath(RunCodeServiceImpl.basePath, OneName.replace(".", "-"));
            path = userOne.appendPath(path, "input.txt");
            FileUtils.writer(path, "", false);
            path = userOne.appendPath(RunCodeServiceImpl.basePath, TwoName.replace(".", "-"));
            path = userOne.appendPath(path, "input.txt");
            FileUtils.writer(path, "", false);
            result = BlackFirstRun(1);
            process = userOne.appendPath(RunCodeServiceImpl.basePath, userOne.getUserName());
            process = userOne.appendPath(process, "input.txt");
            process = FileUtils.read(process);
            if ("".equals(result)) {
                runResult += "winner:none$" + process + "$" + runTime + "$";
            } else if ("no".equals(result)) {
                runResult += "winner:2$" + process + "$" + runTime + "$";
                winnerJurgeTwo = 1;
            } else if ("yes".equals(result)) {
                runResult += "winner:1$" + process + "$" + runTime + "$";
                winnerJurgeOne = 1;
            } else {
                if (result.substring(0, result.indexOf("#")).equals(OneName)) {
                    runResult += "运行错误1$" + result.substring(result.indexOf("#") + 1) + "$";
                    winnerJurgeTwo = 1;
                } else {
                    runResult += "运行错误2$" + result.substring(result.indexOf("#") + 1) + "$";
                    winnerJurgeOne = 1;
                }
            }
        }
        //销毁本地运行产生的文件夹
        userOne.destroy();
        userTwo.destroy();
        finalResult.put("result", runResult);
        if (winnerJurgeOne == 1 && winnerJurgeTwo == 1) {
            Random random = new Random();
            int soon = random.nextInt(100) % 2;
            if (soon == 1) {
                finalResult.put("winner", "userOne");
            } else {
                finalResult.put("winner", "userTwo");
            }
        } else if (winnerJurgeOne == 0 && winnerJurgeTwo == 0) {
            Random random = new Random();
            int soon = random.nextInt(100) % 2;
            if (soon == 1) {
                finalResult.put("winner", "userOne");
            } else {
                finalResult.put("winner", "userTwo");
            }
        } else if (winnerJurgeOne == 1) {
            finalResult.put("winner", "userOne");
        } else {
            finalResult.put("winner", "userTwo");
        }
        return finalResult;
    }


    private String blackFirstRunTool(String firstRun) {
        String errorMessage = "";
        if ("userOne".equals(firstRun)) {
            Map accept = userOne.doOnceRun();

            if (accept.get("timeOut") != null) {
                errorMessage = userOne.getUserName() + "#timeOut#" + accept.get("timeOut");
            } else if (accept.get("error") != null) {
                errorMessage = userOne.getUserName() + "#" + accept.get("error");
            } else {
                userTwo.setInput((String) accept.get("value"));
                runTime += accept.get("time") + "#";
            }
        } else {
            Map accept = userTwo.doOnceRun();
            if (accept.get("timeOut") != null) {
                errorMessage = userTwo.getUserName() + "#" + accept.get("timeOut");
            } else if (accept.get("error") != null) {
                errorMessage = userTwo.getUserName() + "#" + accept.get("error");
            } else {
                userOne.setInput((String) accept.get("value"));
                runTime += accept.get("time") + "#";
            }
        }
        return errorMessage;
    }

    //前者执黑棋运行一个回合,返回值为yes则userOne胜利，no为userTwo胜利，否则为错误信息,如果棋盘被下满则返回空值
    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    private String BlackFirstRun(int index)//index为0userOne执黑棋，为1useTwo执黑棋
    {
        int runTimes = 0;//当tag为1表示黑棋胜，2表示白棋胜
        runTime = "";
        if (index == 0) {
            userOne.setIsMeBlack(1);//1为我是黑棋
            userTwo.setIsMeBlack(-1);//-1为我是白棋
        } else {
            userTwo.setIsMeBlack(1);
            userOne.setIsMeBlack(-1);
        }

        if (index == 1) {
            String result = blackFirstRunTool("userTwo");
            if (result.length() != 0) {
                return result;
            }
        }

        while (runTimes < 20 - index) {
            String result = blackFirstRunTool("userOne");
            if (result.length() != 0) {
                return result;
            }

            if (userOne.check() == 1) {
                return "yes";
            }
            if (runTimes + 1 >= 20 - index) {
                return "";
            }

            result = blackFirstRunTool("userTwo");
            if (result.length() != 0) {
                return result;
            }

            if (userTwo.check() == 1) {
                return "no";
            }
            runTimes += 2;
        }
        return "";
    }

}
